import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:escooter_patcher_flutter/base/base.dart';
import 'package:escooter_patcher_flutter/ble/ble_plugin.dart';
import 'package:escooter_patcher_flutter/operation/operation_controller.dart';
import 'package:escooter_patcher_flutter/operation/operation_view.dart';
import 'package:escooter_patcher_flutter/operation_rs/operation_rs_controller.dart';
import 'package:escooter_patcher_flutter/operation_rs/operation_rs_view.dart';
import 'package:escooter_patcher_flutter/prompt.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

class SearchDeviceController extends BaseController {
  static final _bleUuid1 =
      BleUuid("6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e");
  static final _bleUuid2 =
      BleUuid("6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400002-b5a3-f393-e0a9-e50e24dcca9e", "6e400001-b5a3-f393-e0a9-e50e24dcca9e", "6e400003-b5a3-f393-e0a9-e50e24dcca9e");

  // 扫描到的设备列表
  final devices = <BluetoothDevice>[].obs;

  RxBool searching = false.obs;
  RxBool connecting = false.obs;

  // 当前系统蓝牙状态
  Rx<BluetoothState> btState = BluetoothState.unknown.obs;

  // 搜多到的BLE设备地址
  Set<String> bleDeviceAddress = {};

  final BleManager _bleManager = BleManager();

  @override
  init() {
    EasyLoading.show();
    Future.delayed(const Duration(milliseconds: 500), () async {
      btState.value = await _bleManager.getBtState();
      _bleManager.addSupportedBleServices([
        _bleUuid1,
        _bleUuid2,
      ]);
      _bleManager.onStateChangedCallback = _onBtDeviceStateChangedCallback;

      handlePermissions().then((allGranted) {
        if (allGranted) Future.delayed(const Duration(milliseconds: 200), () => scan());
        EasyLoading.dismiss();
      });
    });
  }

  Future<bool> handlePermissions() async {
    Map<Permission, PermissionStatus> statuses;
    List<Permission> permissions = [];
    if (Platform.isAndroid) {
      var androidInfo = await DeviceInfoPlugin().androidInfo;

      if (androidInfo.version.sdkInt! >= 31) {
        // 申请蓝牙扫描和连接权限
        permissions.add(Permission.bluetoothConnect);
        permissions.add(Permission.bluetoothScan);
      } else {
        // 申请位置权限，用于扫描蓝牙设备
        permissions.add(Permission.location);
      }
    } else {
      // iOS仅申请蓝牙权限
      permissions.add(Permission.bluetooth);
    }

    statuses = await permissions.request();

    var permissionKeys = statuses.keys;

    for (var permission in permissionKeys) {
      var status = statuses[permission]!;
      if (!status.isGranted) {
        if (permission == Permission.bluetooth) {
          Prompt.toast("Please enable BLUETOOTH and allow us to access BLUETOOTH to search your scooters.");
        } else if (permission == Permission.bluetoothScan) {
          Prompt.toast("Please allow us to access BLUETOOTH SCAN to search your scooters.");
        } else if (permission == Permission.bluetoothConnect) {
          Prompt.toast("Please allow us to access BLUETOOTH CONNECT to connect your scooters.");
        } else if (permission == Permission.location) {
          Prompt.toast("Please allow us to access LOCATION to search your scooters.");
        }
        return Future.value(false);
      }
    }

    return Future.value(true);
  }

  Future<bool> scan() async {
    btState.value = await _bleManager.getBtState();
    print("try to scan, bt state: ${btState.value}");
    if (btState.value != BluetoothState.on) {
      Prompt.showMessageDialog("We couldn't start to search devices when the BLUETOOTH state is ${btState.value}.");
      return false;
    }
    if (searching.value) {
      Prompt.toast("Scanning has already started");
      return true;
    }
    bleDeviceAddress.clear();
    devices.clear();
    _bleManager.scan().listen((scanResult) {
      String deviceId = scanResult.device.id.id;
      if (!bleDeviceAddress.contains(deviceId) && scanResult.device.name.isNotEmpty) {
        devices.add(scanResult.device);
        bleDeviceAddress.add(deviceId);
      }
    }, onDone: () => searching.value = false);

    searching.value = true;
    return true;
  }

  bool stopScanning() {
    if (btState.value != BluetoothState.on) {
      return false;
    }
    _bleManager.stopScan();
    searching.value = false;
    return true;
  }

  connect({BluetoothDevice? device, String? name}) {
    showProgress("Connecting...");
    if (searching.value) stopScanning();
    _bleManager.connect(device: device, name: name, flag: 'HOME_SEARCH').then((value) => null);
  }

  showProgress(String msg) {
    EasyLoading.show(status: msg);
  }

  dismissProgress() {
    EasyLoading.dismiss();
  }

  _onBtDeviceStateChangedCallback(BluetoothDevice device, state, {String? flag}) {
    print("bt state changed, device: ${device.name}, state: $state, flag: $flag");
    String deviceName = device.name;
    switch (state) {
      case BluetoothDeviceState.disconnected:
        dismissProgress();
        Prompt.toast('Device has disconnected');
        break;
      case BluetoothDeviceState.connecting:
        break;
      case BluetoothDeviceState.connected:
        dismissProgress();
        Future.delayed(const Duration(milliseconds: 500), () {
          if (deviceName.startsWith("RS-")) {
            Get.to(OperationRSPage(), binding: BindingsBuilder(() {
              Get.lazyPut(() => OperationRSController());
            }));
          } else {
            Get.to(OperationPage(), binding: BindingsBuilder(() {
              Get.lazyPut(() => OperationController());
            }));
          }
        });
        break;
      case BluetoothDeviceState.disconnecting:
        break;
    }
  }
}
